package dao.impl;

import dao.EntityDao;
import dao.UserDao;
import entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.criteria.internal.CriteriaDeleteImpl;
import org.hibernate.query.criteria.internal.CriteriaSubqueryImpl;
import org.hibernate.query.criteria.internal.predicate.ExistsPredicate;
import org.hibernate.query.criteria.internal.predicate.PredicateImplementor;
import util.DBUtils;

import javax.persistence.criteria.*;
import java.util.List;

public class EntityDaoImpl<T> implements EntityDao<T> {
    protected Class<T> tClass = null;
    protected SessionFactory sessionFactory = DBUtils.getSessionFactory();
    public EntityDaoImpl(Class<T> tClass){
        this.tClass = tClass;
    }
    @Override
    public List<T> list() {
        Session session = sessionFactory.openSession();
        session = DBUtils.getCurrentSession();
        List<T> list = null;
        try {
            session.beginTransaction();
            list = session.createSQLQuery("select * from t_user").addEntity(tClass).list();
            session.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            session.close();
        }
        return list;
    }

    @Override
    public T getById(String id) {
        Session session = sessionFactory.openSession();
        T user = null;
        try {
            session.beginTransaction();
            user = session.get(tClass, id);
            CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
            CriteriaQuery<Object> query = criteriaBuilder.createQuery();
            Root<T> root = query.from(tClass);
            session.getTransaction().commit();
            return user;
        }catch (Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            session.close();
        }
        return user;
    }

    @Override
    public void updateById(T t) {
        Session session = sessionFactory.openSession();
        try {
            session.beginTransaction();
            session.update(t);
            session.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            session.close();
        }
    }

    @Override
    public void deleteById(T t) {
        Session session = sessionFactory.openSession();
        try {
            session.beginTransaction();
            session.delete(t);
            session.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            session.close();
        }
    }

    @Override
    public void save(T t) {
        Session session = sessionFactory.openSession();
        try {
            session.beginTransaction();
            session.save(t);
            session.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            session.close();
        }
    }
}
